package com.xinchuang.service.actual.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinchuang.comment.R;
import com.xinchuang.domain.entity.*;
import com.xinchuang.domain.pojo.*;
import com.xinchuang.domain.type.NoticeMainEnum;
import com.xinchuang.domain.vo.PackingOut;
import com.xinchuang.entity.api.MonthTimes;
import com.xinchuang.entity.api.OaUserParam;
import com.xinchuang.entity.api.SubTargetVo;
import com.xinchuang.entity.api.UserApi;
import com.xinchuang.mapper.*;
import com.xinchuang.service.OaUserService;
import com.xinchuang.service.actual.StasticsService;
import com.xinchuang.service.actual.TryOutCountStasticsService;
import com.xinchuang.service.actual.TryOutDeviceModService;
import com.xinchuang.service.actual.TryOutRecordService;
import com.xinchuang.utils.MyUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.ehcache.sizeof.SizeOf;
import org.springframework.stereotype.Service;

import java.time.MonthDay;
import java.util.*;

/**
 * TODO
 *
 * @author zkwczx
 * @version 1.0
 * @date 2023/7/6 20:36
 */
@Service
@RequiredArgsConstructor
public class StasticsServiceImpl implements StasticsService {

    private final StasticsMapper stasticsMapper;

    private final TestNoticeMainTabaleMapper noticeMain;

    private final TestModelSubTableMapper testModelSubTableMapper;

    private final TestRecordMainTableMapper recordMain;

    private final TestNoticeTimeTableMapper testNoticeTimeTableMapper;

    private final TestNoticeConsumableTableMapper consumableTableMapper;

    private final TestNoticeProductionTypeTableMapper productionTypeTableMapper;

    private final TestModelParamMapper testModelParamMapper;

    private final TryOutCountStasticsService tryOutCountStasticsService;

    private final TryOutRecordService tryOutRecordService;

    private final TryOutDeviceModService tryOutDeviceModService;

    private final TestRecordMainTableMapper testRecordMainTableMapper;

    private final TestNoticeTimeMapper testNoticeTimeMapper;

    private final TestNoticeMainTabaleMapper testNoticeMainTabaleMapper;

    private final DictTableMapper dictTableMapper;

    private final UserApiMapper userApiMapper;

    private final OaUserService oaUserService;

    @Override
    public String getTryOutRecordList(JSONObject jsonObject) {
        //jsonobject解析获取每页条数
        Long pageSize = jsonObject.getLong("pageSize");
        //jsonobject解析获取页码
        Long pageNum = jsonObject.getLong("pageNum");
        //jsonobject解析获取模具工号
        String moldId = jsonObject.getString("moldId");
        if (StringUtils.isEmpty(moldId)) {
            moldId = null;
        }
        Page<Map<String, Object>> page = new Page<>(pageNum, pageSize);
        IPage<Map<String, Object>> moldMain = stasticsMapper.getMoldMain(page, moldId, null);
        if (CollectionUtil.isNotEmpty(moldMain.getRecords())) {
            JSONObject json = new JSONObject();
            JSONArray array = new JSONArray();
            JSONObject data;
            for (Map<String, Object> record : moldMain.getRecords()) {
                String noteId = record.get("id").toString();
                TestNoticeMainTabale mainTabale = noticeMain.selectById(noteId);
                TestModelSubTable subTable = testModelSubTableMapper.selectById(mainTabale.getParentPlanSubId());
                TestModelParam modelParam = null;
                String targetCount = "";
                String normalTryOutFee = "";
                String overtimeTryOutFee = "";
                TryOutRecord tryOutRecord = tryOutRecordService.getById(noteId);
                if (ObjectUtil.isNotNull(record.get("moldId"))) {
                    modelParam = testModelParamMapper.selectById(record.get("moldId").toString());
                    if (ObjectUtil.isNotNull(modelParam) && StringUtils.isNotBlank(modelParam.getTargetCount())) {
                        targetCount = modelParam.getTargetCount();
                    }
                } else {
                    targetCount = "0";
                }
                if (ObjectUtil.isNotNull(tryOutRecord)) {
                    normalTryOutFee = MyUtils.getString(tryOutRecord.getNormalTryOutFee());
                    overtimeTryOutFee = MyUtils.getString(tryOutRecord.getOvertimeTryOutFee());
                }
                TryOutDeviceMod tryOutDeviceMod = tryOutDeviceModService.getById(mainTabale.getTryOutDeviceId());
                Double Price = 0D;
                Double NormalTimePrice = 0D;
                Double TimeOutPirce = 0D;
                if (ObjectUtil.isNotEmpty(tryOutDeviceMod)) {
                    Price = MyUtils.getDouble(tryOutDeviceMod.getPrice());
                    if (StringUtils.isNotBlank(tryOutDeviceMod.getNormalTimePrice())) {
                        NormalTimePrice = MyUtils.formatDouble(tryOutDeviceMod.getNormalTimePrice().trim());
                    }
                    if (StringUtils.isNotBlank(tryOutDeviceMod.getTimeOutPirce())) {
                        TimeOutPirce = MyUtils.formatDouble(tryOutDeviceMod.getTimeOutPirce());
                    }
                }
                //
                data = new JSONObject();
                data.put("noteId", record.get("id").toString());
                data.put("moldId", record.get("moldId"));
                //钳工组
                String tongManName = "";
                if (ObjectUtil.isNotNull(modelParam) && StringUtils.isNotBlank(modelParam.getTongmanName())) {
                    OaUserParam oaUserParam = oaUserService.getById(modelParam.getTongmanName());
                    if (ObjectUtil.isNotNull(oaUserParam)) {
                        tongManName = oaUserParam.getName();
                    }
                }
                data.put("tongManName", tongManName);
                //周数
                data.put("weekOfYear", MyUtils.getWeekNum(mainTabale.getCreateTime()));
                //月份
                data.put("month", DateUtil.format(subTable.getPlannedTime(), "MM月"));
                //单价
                data.put("unitPrice", MyUtils.formatDouble(Price));
                //标准时间单价（与设备型号关联）
                data.put("unitPriceOfTime", MyUtils.formatDouble(NormalTimePrice));
                //标准试模费用
                data.put("normalTryOutFee", normalTryOutFee);
                //超时试模费用
                data.put("overtimeTryOutFee", overtimeTryOutFee);
                //试模设备型号
                String tryOutDeviceModel = "";
                TryOutDeviceMod deviceMod = tryOutDeviceModService.getById(mainTabale.getTryOutDeviceId());
                if (ObjectUtil.isNotNull(deviceMod)) {
                    tryOutDeviceModel = MyUtils.getString(deviceMod.getDeviceName());
                }
                data.put("tryOutDeviceModel", tryOutDeviceModel);
                Integer maxTryTimes = null;
                if (StringUtils.isNotBlank(subTable.getTryOutTimes())) {
                    maxTryTimes = Integer.valueOf(subTable.getTryOutTimes());
                }
                String realCountOfYear = "";
                if (null == maxTryTimes) {
                    realCountOfYear = "无";
                } else {
                    realCountOfYear = "T" + maxTryTimes;
                }
                //本月实际试模次数
                data.put("realCountOfYear", realCountOfYear);
                //目标次数
                data.put("targetCount", targetCount);
                int targetCounts = 0;
                if (StringUtils.isNumeric(targetCount)) {
                    targetCounts = Integer.parseInt(targetCount);
                }
                int beyondExpectationCount = 0;
                if (null != maxTryTimes) {
                    beyondExpectationCount = targetCounts - (maxTryTimes + 1);
                    if (beyondExpectationCount > 0) {
                        beyondExpectationCount = 0;
                    } else {
                        beyondExpectationCount = Math.abs(beyondExpectationCount);
                    }
                }
                //超出预期次数
                data.put("beyondExpectationCount", beyondExpectationCount);
                //计划试模日期
                Date plan = ObjectUtil.isNull(subTable) && ObjectUtil.isNull(subTable.getPlannedTime()) ? null : subTable.getPlannedTime();
                data.put("plannedTime", ObjectUtil.isNull(plan) ? "" : DateUtil.format(plan, "yyyy-MM-dd"));
                //实际试模日期
                Date practical = ObjectUtil.isNull(subTable) && ObjectUtil.isNull(subTable.getPracticalTime()) ? null : subTable.getPracticalTime();
                data.put("practicalTryOutDate", ObjectUtil.isNull(practical) ? "" : DateUtil.format(practical, "yyyy-MM-dd"));
                //
                String rectificationAndVerification = "";
                String textureVerification = "";
                String setupVerification = "";
                String unplannedProofing = "";
                String materialVerification = "";
                String setupDeliveryTime = "";
                if (StringUtils.isNotBlank(mainTabale.getSubTarget())) {
                    if (mainTabale.getSubTarget().contains("Z")) {
                        rectificationAndVerification = mainTabale.getSubTarget();
                    } else if (mainTabale.getSubTarget().contains("W")) {
                        textureVerification = mainTabale.getSubTarget();
                    } else if (mainTabale.getSubTarget().contains("G")) {
                        setupVerification = mainTabale.getSubTarget();
                    } else if (mainTabale.getSubTarget().contains("K")) {
                        unplannedProofing = mainTabale.getSubTarget();
                    } else if (mainTabale.getSubTarget().contains("Q")) {
                        materialVerification = mainTabale.getSubTarget();
                    } else if (mainTabale.getSubTarget().contains("P")) {
                        setupDeliveryTime = mainTabale.getSubTarget();
                    }
                }
                //整改验证
                data.put("rectificationAndVerification", rectificationAndVerification);
                //纹理验证
                data.put("textureVerification", textureVerification);
                //设变验证
                data.put("setupVerification", setupVerification);
                //计划外打样
                data.put("unplannedProofing", unplannedProofing);
                //材料验证
                data.put("materialVerification", materialVerification);
                //设变数据下发时间
                data.put("setupDeliveryTime", setupDeliveryTime);
                //是否按时完成
                String pass = "否";
                if (ObjectUtil.isAllNotEmpty(plan, practical)) {
                    if (practical.getTime() <= plan.getTime()) {
                        pass = "是";
                    }
                }
                data.put("isCompletedOnTime", pass);
                String reasonName = "";
                DictTable table = dictTableMapper.selectById(mainTabale.getTryOutReasonId());
                if (ObjectUtil.isNotNull(table)) {
                    reasonName = table.getDicName();
                }
                //试模原因ID
                data.put("reasonName", reasonName);
                //调试（试模工）
                String commissioningEngineer = "";
                if (StringUtils.isNumeric(mainTabale.getTongmanName())) {
                    UserApi userApi = userApiMapper.selectById(mainTabale.getTongmanName());
                    if (ObjectUtil.isNotNull(userApi)) {
                        commissioningEngineer = userApi.getName();
                    }
                }
                data.put("commissioningEngineer", commissioningEngineer);
                //项目经理
                data.put("projectManager", mainTabale.getProjectManager());
                //项目名称
                data.put("projectName", mainTabale.getProjectName());
                //时间处理******************************
                TestNoticeTimeTable timeTable = testNoticeTimeTableMapper.selectOne(
                        new QueryWrapper<TestNoticeTimeTable>()
                                .lambda()
                                .eq(TestNoticeTimeTable::getParentNoticeId, record.get("id"))
                );
                //模具到达时间
                data.put("moldReachedTime", ObjectUtil.isNull(timeTable) ? "" : MyUtils.getLocalDataTimeByString(timeTable.getReachedTime()));
                //上模时间
                long load = testNoticeTimeMapper.getSumTime(record.get("id").toString(), 1);
                data.put("loadMoldTime", MyUtils.getTime(load));
                //等待时间
                long wait = testNoticeTimeMapper.getSumTime(record.get("id").toString(), 2);
                data.put("waitTime", MyUtils.getTime(wait));
                //设备故障(时间)
                long breakdown = testNoticeTimeMapper.getSumTime(record.get("id").toString(), 5);
                data.put("breakdownTime", MyUtils.getTime(breakdown));
                //修模时间
                long fix = testNoticeTimeMapper.getSumTime(record.get("id").toString(), 6);
                data.put("fixTime", MyUtils.getTime(fix));
                //调试时间
                long debug = testNoticeTimeMapper.getSumTime(record.get("id").toString(), 7);
                data.put("debugTime", MyUtils.getTime(debug));
                //样件生产时间
                long demoPoduce = testNoticeTimeMapper.getSumTime(record.get("id").toString(), 3);
                data.put("demoPoduceTime", MyUtils.getTime(demoPoduce));
                //下模时间
                long unload = testNoticeTimeMapper.getSumTime(record.get("id").toString(), 4);
                data.put("unloadTime", MyUtils.getTime(unload));
                //试模总时间（H）无等
                data.put("totalTimeWithoutWait", MyUtils.getTime(load + breakdown + fix + debug + demoPoduce + unload));
                //试模总时间(H)/全
                data.put("totalTime", MyUtils.getTime(load + wait + breakdown + fix + debug + demoPoduce + unload));
                //正常时间
                data.put("normalTime", MyUtils.getTime(load + debug + demoPoduce + unload));
                //异常时间（全）
                data.put("expectTime", MyUtils.getTime(wait + breakdown + fix));
                //异常时间（无等）
                data.put("expectTimeWithoutWait", MyUtils.getTime(breakdown + fix));
                //总费用（无等）
                data.put("totalFeeWithoutWait", MyUtils.getMoney((load + breakdown + fix + debug + demoPoduce + unload), Price));
                //总费用（全）
                data.put("totalFee", MyUtils.getMoney((load + wait + breakdown + fix + debug + demoPoduce + unload), NormalTimePrice));
                //异常费用（全）
                data.put("expectFee", MyUtils.getMoney((wait + breakdown + fix), NormalTimePrice));
                //异常费用（无等）
                data.put("expectTimeWithOutWait", MyUtils.getMoney((breakdown + fix), NormalTimePrice));
                String tryOutLoss = "0";
                if (beyondExpectationCount > 0) {
                    tryOutLoss = data.getString("totalFee");
                } else {
                    tryOutLoss = data.getString("expectFee");
                }
                //试模损失（全）
                data.put("tryOutLoss", tryOutLoss);
                String loss = "0";
                if (beyondExpectationCount > 0) {
                    loss = data.getString("totalFeeWithoutWait");
                } else {
                    loss = data.getString("expectTimeWithOutWait");
                }
                //损失
                data.put("loss", loss);
                //试模地点
                String tryOutPlace = "";
                DictTable dictTable = dictTableMapper.selectById(mainTabale.getTryOutCompanyId());
                if (ObjectUtil.isNotNull(dictTable)) {
                    tryOutPlace = dictTable.getDicName();
                }
                data.put("tryOutPlace", tryOutPlace);
                array.add(data);
            }
            json.put("totalCount", moldMain.getTotal());
            json.put("dataList", array);
            return JSON.toJSONString(R.data(json));
        }
        return JSON.toJSONString(R.success("无数据"));
    }

    @Override
    public String packingOutList(JSONObject jsonObject) {
        //jsonobject解析获取模具工号
        String moldId = jsonObject.getString("moldId");
        //jsonobject解析获取项目名称
        String projectName = jsonObject.getString("projectName");
        //jsonobject解析获取页码
        Long pageNum = jsonObject.getLong("pageNum");
        //jsonobject解析获取每页数量
        Long pageSize = jsonObject.getLong("pageSize");
        if (StringUtils.isEmpty(moldId)) {
            moldId = null;
        }
        if (StringUtils.isEmpty(projectName)) {
            projectName = null;
        }
        Page<Map<String, Object>> page = new Page<>(pageNum, pageSize);
        IPage<PackingOut> moldMain = stasticsMapper.packingOut(page, moldId, projectName);
        if (CollectionUtil.isNotEmpty(moldMain.getRecords())) {
            JSONObject json = new JSONObject();
            JSONArray array = new JSONArray();
            JSONObject data;
            for (PackingOut record : moldMain.getRecords()) {
                //生产模数
                Integer production = MyUtils.getInteger(record.getProductionQuantity());
                //调试模数
                Integer modulus = MyUtils.getInteger(record.getModulusQuantity());
                //合格品数
                Integer qualified = MyUtils.getInteger(record.getQualifiedQuantity());
                //让步接收数
                Integer receive = MyUtils.getInteger(record.getReceiveQuantity());
                data = new JSONObject();
                String name = "";
                String unit = "";
                if (StringUtils.isNotBlank(record.getType())) {
                    name = record.getType();
                    unit = record.getMeasurement();
                 /*   if (record.getType().equals("1")) {
                        name = "材料";
                        unit = "KG";
                    } else if (record.getType().equals("2")) {
                        name = "纸箱";
                        unit = "个";
                    } else {
                        name = "包装袋";
                        unit = "个";
                    }*/
                } else {
                    name = "无";
                    unit = "无";
                }
                data.put("moldId", MyUtils.getString(record.getMoldId()));
                data.put("projectName", MyUtils.getString(record.getProjectName()));
                data.put("moldWeight", MyUtils.getString(record.getMoldWeight()));
                //领用物资类
                data.put("receivedType", name);
                //退库
                data.put("returnCount", StringUtils.isBlank(record.getStock()) ? "0" : record.getStock());
                //让步接收数
                data.put("concessionalReceivingCount", receive);
                //消耗数量
                data.put("consumeCount", StringUtils.isBlank(record.getConsumption()) ? "0" : record.getConsumption());
                //领用日期
                data.put("receiveDate", ObjectUtil.isNull(record.getReachedTime()) ? "" : DateUtil.format(record.getReachedTime(), "yyyy-MM-dd"));
                //规格
                data.put("specification", StringUtils.isBlank(record.getSpecification()) ? "" : record.getSpecification());
                //生产模数
                data.put("produceMoldCount", production);
                //调试模数
                data.put("debugMoldCount", modulus);
                //合格品数
                data.put("qualifiedMoldCount", qualified);
                //单位
                data.put("unit", unit);
                //领用数量
                data.put("receiveCount", StringUtils.isBlank(record.getClaim()) ? "0" : record.getClaim());
                //超额数量
                data.put("excessCount", MyUtils.getNum(data.get("consumeCount").toString(), data.get("receiveCount").toString()));
                array.add(data);
            }
            json.put("totalCount", moldMain.getTotal());
            json.put("dataList", array);
            return JSON.toJSONString(R.data(json));
        }
        return JSON.toJSONString(R.success("无数据"));
    }

    @Override
    public String weekYearMonthStastics(JSONObject jsonObject) {
        //jsonobject解析获取查询第几周
        Integer week = jsonObject.getInteger("week");
        //jsonobject解析获取查询第几月
        Integer month = jsonObject.getInteger("month");
        //jsonobject解析获取查询哪一年
        String year = jsonObject.getString("year");
        String startTime = "";
        String endTime = "";
        if (null != week) {
            startTime = MyUtils.getWeekStartDays(week);
            endTime = MyUtils.getWeekEndDays(week);
        } else if (null != month) {
            startTime = MyUtils.getMonthStartDay(null, month);
            endTime = MyUtils.getMonthEndDay(null, month);
        } else if (StringUtils.isNotBlank(year)) {
            startTime = year + "-01-01 00:00:00";
            endTime = year + "-12-31 23:59:59";
        }
        List<String> customerName = stasticsMapper.getMoldCustomerName();
        if (CollectionUtil.isNotEmpty(customerName)) {
            JSONObject json = new JSONObject();
            JSONArray array = new JSONArray();
            JSONObject data;
            for (String name : customerName) {
                if (StringUtils.isBlank(name)) {
                    continue;
                }
                data = new JSONObject();
                String companyName = "";
                DictTable table = dictTableMapper.selectById(name);
                if (ObjectUtil.isNotNull(table)) {
                    companyName = table.getDicName();
                } else {
                    companyName = name;
                }
                //试模单位名称
                data.put("companyName", companyName);
                //试模套数
                Integer numAll = stasticsMapper.getTestNumAll(name, startTime, endTime);
                data.put("numOfTestSets", numAll);
                //按时完成套数
                Integer testDoneNumAll = stasticsMapper.getTestDoneNumAll(name, startTime, endTime);
                data.put("numOfOnTimeSets", testDoneNumAll);
                //按时完成率
                double done = 0.0;
                if (numAll > 0 && testDoneNumAll > 0) {
                    done = testDoneNumAll / (double) numAll * 100;
                }
                data.put("rateOfOnTime", MyUtils.formatDouble(done));
                //T0试模套数
                Integer numOfSets = stasticsMapper.getTestNumT0All(name, startTime, endTime);
                data.put("numOfSets", numOfSets);
                //T0按时套数
                Integer numOfOnTime = stasticsMapper.getTestDoneNumT0All(name, startTime, endTime);
                data.put("numOfOnTime", numOfOnTime);
                //T0按时完成率
                double t0Done = 0.0;
                if (numOfOnTime > 0 && numOfSets > 0) {
                    t0Done = numOfOnTime / (double) numOfSets * 100;
                }
                data.put("rateOfOnTimeOfT0", MyUtils.formatToDouble(t0Done));
                String allTime = "0";
                String allMoney = "0";
                String errorTime = "0";
                String errorMoney = "0";
                List<TestNoticeMainTabale> mains = testNoticeMainTabaleMapper.getCustomerMains(name, startTime, endTime);
                if (CollectionUtil.isNotEmpty(mains)) {
                    long time = 0L;
                    long error = 0L;
                    double moneyTime = 0;
                    double moneyError = 0;
                    for (TestNoticeMainTabale mainTabale : mains) {
                        //时间
                        //上模时间
                        long load = testNoticeTimeMapper.getSumTime(mainTabale.getId(), 1);
                        //等待时间
                        long wait = testNoticeTimeMapper.getSumTime(mainTabale.getId(), 2);
                        //设备故障(时间)
                        long breakdown = testNoticeTimeMapper.getSumTime(mainTabale.getId(), 5);
                        //修模时间
                        long fix = testNoticeTimeMapper.getSumTime(mainTabale.getId(), 6);
                        //调试时间
                        long debug = testNoticeTimeMapper.getSumTime(mainTabale.getId(), 7);
                        //样件生产时间
                        long demoPoduce = testNoticeTimeMapper.getSumTime(mainTabale.getId(), 3);
                        //下模时间
                        long unload = testNoticeTimeMapper.getSumTime(mainTabale.getId(), 4);
                        //试模总时间(H)/全
                        time += load + wait + breakdown + fix + debug + demoPoduce + unload;
                        //异常时间（全）
                        error += wait + breakdown + fix;
                        double NormalTimePrice = 0D;
                        if (StringUtils.isNotBlank(mainTabale.getTryOutDeviceId())) {
                            TryOutDeviceMod tryOutDeviceMod = tryOutDeviceModService.getById(mainTabale.getTryOutDeviceId());
                            if (ObjectUtil.isNotEmpty(tryOutDeviceMod)) {
                                if (StringUtils.isNotBlank(tryOutDeviceMod.getNormalTimePrice())) {
                                    NormalTimePrice = MyUtils.formatDouble(tryOutDeviceMod.getNormalTimePrice().trim());
                                }
                            }
                        }
                        //总费用（全）
                        moneyTime += MyUtils.getMoneyDouble((load + wait + breakdown + fix + debug + demoPoduce + unload), NormalTimePrice);
                        //异常费用（全）
                        moneyError = MyUtils.getMoneyDouble((wait + breakdown + fix), NormalTimePrice);

                    }
                    allTime = MyUtils.getTime(time);
                    errorTime = MyUtils.getTime(error);
                    allMoney = MyUtils.formatDouble(moneyTime);
                    errorMoney = MyUtils.formatDouble(moneyError);
                }
                //总试模时间（H）
                data.put("totalTime", allTime);
                //总试模费用（元）
                data.put("totalTryOutFee", allMoney);
                //异常时间（H)
                data.put("exceptTime", errorTime);
                //损失费用(元）
                data.put("lossFee", errorMoney);
                array.add(data);
            }
            json.put("from", startTime);
            json.put("to", endTime);
            json.put("dataList", array);
            return JSON.toJSONString(R.data(json));
        }
        return JSON.toJSONString(R.success("无数据"));
    }

    @Override
    public String lossStastics(JSONObject jsonObject) {
        String year = jsonObject.getString("year");
        JSONObject json = new JSONObject();
        JSONArray detailOfYearData = new JSONArray();
        {
            String startTime;
            String endTime;
            JSONObject data;
            for (int i = 1; i <= 12; i++) {
                startTime = MyUtils.getMonthStartDay(year, i);
                endTime = MyUtils.getMonthEndDay(year, i);
                data = new JSONObject();
                //月份
                data.put("month", i + "月");
                //试模次数
                List<MonthTimes> timeSum = stasticsMapper.getMonthTryOutTimeSum(startTime, endTime);
                int tryOutTime = 0;
                if (CollectionUtil.isNotEmpty(timeSum)) {
                    tryOutTime = timeSum.size();
//                    for (MonthTimes monthDay : timeSum) {
//                        if (null != monthDay.getTryTimes()) {
//                            tryOutTime += monthDay.getTryTimes() + 1;
//                        }
//                    }
                }
                data.put("tryOutTime", tryOutTime);
                //5次内试模数量
                data.put("tryOutTimeInFive", stasticsMapper.getFiveTestTimes(startTime, endTime));
                //正常次数试模比例
                List<Map<String, Integer>> testAndTargetCoutes = stasticsMapper.getAllTestAndTargetCoutes(startTime, endTime);
                double rateOfNormalTimes = 0;
                if (CollectionUtil.isNotEmpty(testAndTargetCoutes)) {
                    int good = 0;
                    for (Map<String, Integer> testAndTargetCoute : testAndTargetCoutes) {
                        if (testAndTargetCoute.get("counts") >= testAndTargetCoute.get("times")) {
                            good++;
                        }
                    }
                    rateOfNormalTimes = good / (double) testAndTargetCoutes.size() * 100;
                }
                data.put("rateOfNormalTimes", MyUtils.formatDouble(rateOfNormalTimes));
                //
                List<Map<String, String>> monthPrice = stasticsMapper.getMonthPrice(startTime, endTime);
                String allTime = "0";
                String allMoney = "0";
                String errorTime = "0";
                String errorMoney = "0";
                String bebugMonty = "0";
                String bebugTime = "0";
                String errorScale = "0";
                String bebugScale = "0";
                if (CollectionUtil.isNotEmpty(monthPrice)) {
                    long time = 0L;
                    long error = 0L;
                    long bebug = 0L;
                    double moneyTime = 0;
                    double moneyError = 0;
                    double moneyBebug = 0;
                    for (Map<String, String> map : monthPrice) {
                        //时间
                        //上模时间
                        long load = testNoticeTimeMapper.getSumTime(map.get("id"), 1);
                        //等待时间
                        long wait = testNoticeTimeMapper.getSumTime(map.get("id"), 2);
                        //设备故障(时间)
                        long breakdown = testNoticeTimeMapper.getSumTime(map.get("id"), 5);
                        //修模时间
                        long fix = testNoticeTimeMapper.getSumTime(map.get("id"), 6);
                        //调试时间
                        long debug = testNoticeTimeMapper.getSumTime(map.get("id"), 7);
                        //样件生产时间
                        long demoPoduce = testNoticeTimeMapper.getSumTime(map.get("id"), 3);
                        //下模时间
                        long unload = testNoticeTimeMapper.getSumTime(map.get("id"), 4);
                        //试模总时间(H)/全
                        time += load + wait + breakdown + fix + debug + demoPoduce + unload;
                        //异常时间（全）
                        error += wait + breakdown + fix;
                        double NormalTimePrice = Double.parseDouble(map.get("price"));
                        //总费用（全）
                        moneyTime += MyUtils.getMoneyDouble(time, NormalTimePrice);
                        //异常费用（全）
                        moneyError = MyUtils.getMoneyDouble(error, NormalTimePrice);
                        //损失时间
                        bebug = breakdown + fix;
                        //损失费用
                        moneyBebug = MyUtils.getMoneyDouble(bebug, NormalTimePrice);
                    }
                    allTime = MyUtils.getTime(time);
                    errorTime = MyUtils.getTime(error);
                    bebugTime = MyUtils.getTime(bebug);
                    allMoney = MyUtils.formatDouble(moneyTime);
                    errorMoney = MyUtils.formatDouble(moneyError);
                    bebugMonty = MyUtils.formatDouble(moneyBebug);
                    if (moneyTime > 0) {
                        errorScale = MyUtils.formatDouble(moneyError / moneyTime * 100);
                        bebugScale = MyUtils.formatDouble(moneyBebug / moneyTime * 100);
                    }
                }
                //试模总费用
                data.put("totalFee", allMoney);
                //异常损失费用
                data.put("exceptLoss", errorMoney);
                //异常损失占比
                data.put("rateOfexceptLoss", errorScale);
                //试模损失
                data.put("tryOutLoss", bebugMonty);
                //试模损失占比
                data.put("rateOfTryOutLoss", bebugScale);
                //
                String rateOfExceptLossInNormalTimes = "0";
                List<String> moldId = stasticsMapper.getMonthTrueMoldId(startTime, endTime);
                if (CollectionUtil.isNotEmpty(moldId)) {
                    double all = 0;
                    double error = 0;
                    for (String s : moldId) {
                        List<Map<String, String>> monthTruePriceId = stasticsMapper.getMonthTruePriceId(s, startTime, endTime);
                        if (CollectionUtil.isNotEmpty(monthTruePriceId)) {
                            for (Map<String, String> map : monthTruePriceId) {
                                long timeSumTime = stasticsMapper.getTimeSumTime(map.get("id"));
                                if (timeSumTime > 0) {
                                    long timeSumErrorTime = stasticsMapper.getTimeSumErrorTime(map.get("id"));
                                    all += MyUtils.getMoneyDouble(timeSumTime, Double.parseDouble(map.get("price")));
                                    error += MyUtils.getMoneyDouble(timeSumErrorTime, Double.parseDouble(map.get("price")));
                                }
                            }
                        }
                    }
                    if (all > 0) {
                        rateOfExceptLossInNormalTimes = MyUtils.formatDouble(error / all * 100);
                    }
                }
                //正常次数内异常损失占比
                data.put("rateOfExceptLossInNormalTimes", rateOfExceptLossInNormalTimes);
                detailOfYearData.add(data);
            }
        }
        json.put("detailOfYearData", detailOfYearData);
        JSONArray exceptData = new JSONArray();
        {
            for (int i = 1; i <= 12; i++) {
                List<Map<String, Long>> monthTimeAll = stasticsMapper.getMonthTimeAll(
                        MyUtils.getMonthStartDay(year, i),
                        MyUtils.getMonthEndDay(year, i)
                );
                exceptData.add(MyUtils.getMonthTimeAll(i, monthTimeAll));
            }
        }
        json.put("exceptData", exceptData);
        //试模分析-试模目的（费用）
        JSONArray targetData = new JSONArray();
        {
            JSONObject data;
            for (int i = 1; i <= 12; i++) {
                data = new JSONObject();
                //月份
                data.put("month", i + "月");
                Double T0Verification = 0D;
                Double rectificationAndVerification = 0D;
                Double textureVerification = 0D;
                Double setupVerification = 0D;
                Double unplannedProofing = 0D;
                Double materialVerification = 0D;
                Double setupDeliveryTime = 0D;
                List<SubTargetVo> subTargetAll = stasticsMapper.getSubTargetAll(
                        MyUtils.getMonthStartDay(year, i),
                        MyUtils.getMonthEndDay(year, i)
                );
                if (CollectionUtil.isNotEmpty(subTargetAll)) {
                    for (SubTargetVo subTargetVo : subTargetAll) {
                        if (StringUtils.isNotBlank(subTargetVo.getId()) && StringUtils.isNotBlank(subTargetVo.getNormalTimePrice())) {
                            double price = MyUtils.formatDouble(subTargetVo.getNormalTimePrice());
                            Long timeSum = stasticsMapper.getTimeSum(subTargetVo.getId());
                            if (null != subTargetVo.getTryOutTimes() && subTargetVo.getTryOutTimes() == 0) {
                                if (null != timeSum) {
                                    T0Verification += MyUtils.getMoneyDouble(timeSum, price);
                                }
                            } else if (StringUtils.isNotBlank(subTargetVo.getSubTarget())) {
                                if (subTargetVo.getSubTarget().contains("Z")) {
                                    if (null != timeSum) {
                                        rectificationAndVerification += MyUtils.getMoneyDouble(timeSum, price);
                                    }
                                } else if (subTargetVo.getSubTarget().contains("W")) {
                                    if (null != timeSum) {
                                        textureVerification += MyUtils.getMoneyDouble(timeSum, price);
                                    }
                                } else if (subTargetVo.getSubTarget().contains("G")) {
                                    if (null != timeSum) {
                                        setupVerification += MyUtils.getMoneyDouble(timeSum, price);
                                    }
                                } else if (subTargetVo.getSubTarget().contains("K")) {
                                    if (null != timeSum) {
                                        unplannedProofing += MyUtils.getMoneyDouble(timeSum, price);
                                    }
                                } else if (subTargetVo.getSubTarget().contains("Q")) {
                                    if (null != timeSum) {
                                        materialVerification += MyUtils.getMoneyDouble(timeSum, price);
                                    }
                                } else if (subTargetVo.getSubTarget().contains("P")) {
                                    if (null != timeSum) {
                                        setupDeliveryTime += MyUtils.getMoneyDouble(timeSum, price);
                                    }
                                }
                            }
                        }
                    }
                }
                //T0验证
                data.put("T0Verification", MyUtils.formatToDouble(T0Verification));
                //整改验证
                data.put("rectificationAndVerification", MyUtils.formatToDouble(rectificationAndVerification));
                //纹理验证
                data.put("textureVerification", MyUtils.formatToDouble(textureVerification));
                //设变验证
                data.put("setupVerification", MyUtils.formatToDouble(setupVerification));
                //计划外打样
                data.put("unplannedProofing", MyUtils.formatToDouble(unplannedProofing));
                //材料验证
                data.put("materialVerification", MyUtils.formatToDouble(materialVerification));
                //有计划无整改打样
                data.put("planWithoutModificationProofing", MyUtils.formatToDouble(setupDeliveryTime));
                targetData.add(data);
            }
        }
        json.put("targetData", targetData);
        return JSON.toJSONString(R.data(json));
    }

    @Override
    public String packingOutStastics(JSONObject jsonObject) {
        //jsonobject解析获取项目名称
        String projectName = jsonObject.getString("projectName");
        //jsonobject解析获取领用数量
        String receivedCount = jsonObject.getString("receivedCount");
        //jsonobject解析获取合格品数量
        String qualifiedCount = jsonObject.getString("qualifiedCount");
        List<Map<String, Object>> consumable = stasticsMapper.getMainConsumable(projectName);
        if (CollectionUtil.isNotEmpty(consumable)) {
            JSONObject json = new JSONObject();
            JSONArray array = new JSONArray();
            JSONObject data;
            for (Map<String, Object> map : consumable) {
                data = new JSONObject();
                String name = "";
                String materialSpec = "";
                if (ObjectUtil.isNotEmpty(map.get("specification"))) {
                    materialSpec = map.get("specification").toString();
                } else {
                    continue;
                }
                if (ObjectUtil.isNotEmpty(map.get("type"))) {
                    name = map.get("type") + "";
                /*    Integer type = Integer.valueOf(map.get("type").toString());
                    if (type == 1) {
                        name = "材料";
                    } else if (type == 2) {
                        name = "纸箱";
                    } else {
                        name = "包装袋";
                    }*/
                }
                //物资类别名称
                data.put("typeName", name);
                //规格
                data.put("materialSpec", materialSpec);
                //领用数量
                data.put("receivedCount", null != map.get("claim") ? map.get("claim") : 0);
//                Long okWay = stasticsMapper.getOkWay(projectName);
//                if (null == okWay) {
//                    okWay = 0L;
//                }
                //合格品数量
                data.put("qualifiedCount", null != map.get("qualified") ? map.get("qualified") : 0);
                array.add(data);
            }
            json.put("dataList", array);
            return JSON.toJSONString(R.data(json));
        }
        return JSON.toJSONString(R.success("无数据"));
    }

    @Override
    public String tryOutCountStastics(JSONObject jsonObject) {
        //jsonobject解析获取模具工号
        String moldId = jsonObject.getString("moldId");
        //jsonobject解析获取模具名称
        String moldName = jsonObject.getString("moldName");
        //jsonobject解析获取外观要求
//        String appearanceRequire = jsonObject.getString("appearanceRequire");
        //jsonobject解析获取项目经理
//        String projectManagerName = jsonObject.getString("projectManagerName");
        //jsonobject解析获取计划T0时间
//        String plannedT0Time = jsonObject.getString("plannedT0Time");
        //jsonobject解析获取合计目标试模次数
//        String totalTargetTryOutTime = jsonObject.getString("totalTargetTryOutTime");
        //jsonobject解析获取光样前
//        String appearanceRequirement = jsonObject.getString("appearanceRequirement");
        //jsonobject解析获取纹理验证
//        String textureVerification = jsonObject.getString("textureVerification");
        //jsonobject解析获取页码
        Long pageNum = jsonObject.getLong("pageNum");
        //jsonobject解析获取每页条数
        Long pageSize = jsonObject.getLong("pageSize");
        Page<TestRecordMainTable> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<TestRecordMainTable> wrapper = new LambdaQueryWrapper<>();
        List<String> list = new ArrayList<>();
        if (StringUtils.isNotBlank(moldId)) {
            list.add(moldId);
        }
        if (StringUtils.isNotBlank(moldName)) {
            List<TestModelParam> testModelParams = testModelParamMapper.selectList(new LambdaQueryWrapper<TestModelParam>()
                    .eq(TestModelParam::getMoldName, moldName));
            if (CollectionUtil.isNotEmpty(testModelParams)) {
                for (TestModelParam testModelParam : testModelParams) {
                    list.add(testModelParam.getMoldId());
                }
            }
        }
        if (CollectionUtil.isNotEmpty(list)) {
            wrapper.in(TestRecordMainTable::getMoldId, list);
        }
        Page<TestRecordMainTable> recordMainTablePage = recordMain.selectPage(page, wrapper);
        if (CollectionUtil.isNotEmpty(recordMainTablePage.getRecords())) {
            JSONObject json = new JSONObject();
            JSONArray array = new JSONArray();
            JSONObject data;
            for (TestRecordMainTable record : recordMainTablePage.getRecords()) {
                data = new JSONObject();
                String moldNames = "";
                if (StringUtils.isNotEmpty(record.getMoldId())) {
                    TestModelParam modelParam = testModelParamMapper.selectById(record.getMoldId());
                    if (ObjectUtil.isNotEmpty(modelParam) && StringUtils.isNotBlank(modelParam.getMoldName())) {
                        moldNames = modelParam.getMoldName();
                    }
                }
                testModelParamMapper.selectById(record.getMoldId());
                String appearanceRequirement = "";
                String textureVerification = "";
                String remark = "";
                TryOutCountStastics countStastics = tryOutCountStasticsService.getById(record.getMoldId());
                if (ObjectUtil.isNotEmpty(countStastics)) {
                    appearanceRequirement = MyUtils.getString(countStastics.getAppearanceRequirement());
                    textureVerification = MyUtils.getString(countStastics.getTextureVerification());
                    remark = MyUtils.getString(countStastics.getRemark());
                }
                //模具工号
                data.put("moldId", StringUtils.isBlank(record.getMoldId()) ? "" : record.getMoldId());
                //模具名称
                data.put("moldName", moldNames);
                //外观要求
                String appearanceRequire = "";
                //零件厂ID
                String partFactoryId = "";
                //项目经理
                String projectManagerName = "";
                if (StringUtils.isNotBlank(record.getMoldId())) {
                    TestModelParam modelParam = testModelParamMapper.selectById(record.getMoldId());
                    if (ObjectUtil.isNotNull(modelParam)) {
                        appearanceRequire = modelParam.getMoldLook();
                        partFactoryId = modelParam.getPartsFactoryId();
                        if (StringUtils.isNotBlank(modelParam.getProjectManager())) {
                            OaUserParam byId = oaUserService.getById(modelParam.getProjectManager());
                            if (ObjectUtil.isNotNull(byId)) {
                                projectManagerName = byId.getName();
                            }
                        }
                    }
                }
                data.put("appearanceRequire", appearanceRequire);
                data.put("partFactoryId", partFactoryId);
                data.put("projectManagerName", projectManagerName);
                //计划T0时间
                Date time = stasticsMapper.getPlanTimeByMold(record.getMoldId());
                data.put("plannedT0Time", null == time ? "" : DateUtil.format(time, "yyyy-MM-dd"));
                //光样前
                data.put("appearanceRequirement", appearanceRequirement);
                //纹理验证
                data.put("textureVerification", textureVerification);
                //合计目标试模次数
//                Integer testMoldNumber = stasticsMapper.getTestMoldNumber(record.getMoldId());
                int testMoldNumber = 0;
                if (StringUtils.isNumeric(appearanceRequirement)) {
                    testMoldNumber += Integer.parseInt(appearanceRequirement);
                }
                if (StringUtils.isNumeric(textureVerification)) {
                    testMoldNumber += Integer.parseInt(textureVerification);
                }
                data.put("totalTargetTryOutTime", testMoldNumber);
                //备注
                data.put("remark", remark);
                array.add(data);
            }
            json.put("dataList", array);
            json.put("totalNum", recordMainTablePage.getTotal());
            return JSON.toJSONString((R.data(json)));
        }
        return JSON.toJSONString(R.success("无数据"));
    }

    @Override
    public String saveTryOutCountStastics(JSONObject jsonObject) {
        //jsonobject解析获取数据列表
        if (CollectionUtil.isNotEmpty(jsonObject.getJSONArray("dataList"))) {
            List<TryOutCountStastics> list = jsonObject.getJSONArray("dataList").toJavaList(TryOutCountStastics.class);
            tryOutCountStasticsService.saveOrUpdateBatch(list);
            return JSON.toJSONString(R.success("保存成功"));
        }
        return JSON.toJSONString(R.success("无数据"));
    }

    @Override
    public String saveTryOutRecordList(JSONObject jsonObject) {
        //jsonobject解析获取统计数据数组对象
        if (CollectionUtil.isNotEmpty(jsonObject.getJSONArray("dataList"))) {
            List<TryOutRecord> list = jsonObject.getJSONArray("dataList").toJavaList(TryOutRecord.class);
            tryOutRecordService.saveOrUpdateBatch(list);
            return JSON.toJSONString(R.success("保存成功"));
        }
        return JSON.toJSONString(R.success("无数据"));
    }

    @Override
    public String getProjectNameList() {
        List<TestModelParam> testModelParams = testModelParamMapper.selectList(null);
        if (CollectionUtil.isNotEmpty(testModelParams)) {
            Set<String> names = new HashSet<>();
            for (TestModelParam testModelParam : testModelParams) {
                if (StringUtils.isNotBlank(testModelParam.getProjectName())) {
                    names.add(testModelParam.getProjectName().trim());
                }
            }
            JSONArray array = new JSONArray();
            for (String name : names) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("projectName", name);
                array.add(jsonObject);
            }
            return JSON.toJSONString(R.data(array));
        }
        return JSON.toJSONString(R.success("无数据"));
    }

}
